//package cc.magicjson;
//
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.boot.context.event.ApplicationReadyEvent;
//import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
//import org.springframework.boot.web.server.WebServerFactoryCustomizer;
//import org.springframework.context.ConfigurableApplicationContext;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.event.EventListener;
//
//import java.io.IOException;
//import java.net.ServerSocket;
//
//@SpringBootApplication
//public class GracefulShutdownApplication1 {
//
//    @Value("${server.default-port}")
//    private int defaultPort;
//
//    @Value("${server.available-ports}")
//    private int[] availablePorts;
//
//    private static ConfigurableApplicationContext context;
//
//    public static void main(String[] args) {
//        context = SpringApplication.run(GracefulShutdownApplication1.class, args);
//    }
//
//    @Bean
//    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer() {
//        return factory -> {
//            int port = getAvailablePort(defaultPort, availablePorts);
//            System.setProperty("server.port", String.valueOf(port));
//            factory.setPort(port);
//        };
//    }
//
//    @EventListener(ApplicationReadyEvent.class)
//    public void onApplicationReady() {
//        int port = Integer.parseInt(System.getProperty("server.port"));
//        if (port != defaultPort) {
//            killProcessUsingPort(defaultPort);
//            restartOnDefaultPort();
//        }
//    }
//
//    private int getAvailablePort(int defaultPort, int[] availablePorts) {
//        if (!isPortInUse(defaultPort)) {
//            return defaultPort;
//        }
//
//        for (int port : availablePorts) {
//            if (!isPortInUse(port)) {
//                return port;
//            }
//        }
//
//        throw new IllegalStateException("No available ports in the specified range.");
//    }
//
//    private boolean isPortInUse(int port) {
//        try (ServerSocket socket = new ServerSocket(port)) {
//            return false;
//        } catch (IOException e) {
//            return true;
//        }
//    }
//
//    private void killProcessUsingPort(int port) {
//        String os = System.getProperty("os.name").toLowerCase();
//        String command;
//
//        if (os.contains("win")) {
//            command = String.format("cmd /c netstat -ano | findstr :%d | findstr LISTENING", port);
//            try {
//                Process process = Runtime.getRuntime().exec(command);
//                process.waitFor();
//                String output = new String(process.getInputStream().readAllBytes());
//                String[] lines = output.split("\n");
//                for (String line : lines) {
//                    if (line.contains("LISTENING")) {
//                        String pid = line.trim().split("\\s+")[4];
//                        Runtime.getRuntime().exec("cmd /c taskkill /PID " + pid + " /F");
//                    }
//                }
//            } catch (IOException | InterruptedException e) {
//                throw new RuntimeException("Failed to kill process using port " + port, e);
//            }
//        } else {
//            command = String.format("lsof -t -i:%d | xargs kill -9", port);
//            try {
//                Runtime.getRuntime().exec(new String[]{"bash", "-c", command});
//            } catch (IOException e) {
//                throw new RuntimeException("Failed to kill process using port " + port, e);
//            }
//        }
//    }
//
//    private void restartOnDefaultPort() {
//        if (context != null) {
//            context.close();
//        }
//
//        System.setProperty("server.port", String.valueOf(defaultPort));
//        SpringApplication app = new SpringApplication(GracefulShutdownApplication1.class);
//        context = app.run();
//    }
//}
